/***********************************************************************************************************************
 * ############################################# Application AdewebLite #############################################
 * AdewebLite Android est une application permettant de consulter des emplois du temps fournis par l'université UHP
 * avec ou sans connexion internet (informations gardées en mémoire à chaque synchronisation). Et utilisant la web
 * API ADE pour collecter les données.
 * @author Andrianjafintrimo Victor, Zanette Sébastien
 * 
 * Basée sur l'application du même nom, utilisant le flux RSS (données à traiter), de :
 * @author Schnell Michaël, Zanette Sébastien
 * **********************************************************************************************************************
 */

package ade.screen;

import greendroid.app.GDListActivity;
import greendroid.widget.ActionBarItem;
import greendroid.widget.ActionBarItem.Type;
import greendroid.widget.ItemAdapter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import ade.database.Database;
import ade.schedule.*;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.widget.*;
import greendroid.widget.item.*;

/**
 * Vue affichant les informations d'un cour (détail d'un cours).
 *
 * @author Zanette Sébastien,
 * @author Andrianjafintrimo Victor
 */
public class LessonScreen extends GDListActivity implements UpdateListener {

    /**
     * Composant graphique utilisé pour afficher ce cours.
     */
    private ListView liste;
    /**
     * Liste de composant graphiques utilisés pour afficher ce cours.
     */
    protected List<Item> items;
    /**
     * Conteneur d'information de ce cours.
     */
    protected Lesson lesson;
    /**
     * Boite de dialogue affichant un chargement lorsqu'un emploi du temps est
     * mis à jour.
     */
    protected ProgressDialog updateDialog;
    /**
     * ID de l'élément d'édition dans la barre d'action.
     */
    protected static final int ITEM_EDIT = 1;
    /**
     * Ancienne instance du cours, utilisée pour montrer les changement lors
     * d'un update
     */
    protected Lesson oldS;
    /*
     * flag pour savoir si il y a eu un changement important de l'emploi du
     * temps
     */
    private boolean changement;

    private static final String NO_TEACHER = "Aucun enseignant";
    private static final String NO_ROOM = "Aucune salle";
    private static final String NO_GROUP = "Aucun groupe";
    private static final String NO_MODIF = "Aucun modification";
    
    private static final String STATUS_NORMAL = "Normal";
    private static final String STATUS_IMPORTANT = "Important";
    private static final String STATUS_EXAMEN = "Examen";
    /*
     *
     */
    /**
     * Initialise la vue.
     * @param savedInstanceState 
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.lesson = this.getIntentLesson();
        /*
         * S'il y a eu un changement "important" du cour on met en valeur les
         * changements et on repositionne le statut CHANGE car l'utilisateur
         * vient de consulter le cours
         */
        if (this.lesson.getChange() == Lesson.BIG_CHANGE) {
            this.montrerChangement();
            this.lesson.setChange(Lesson.NO_CHANGE);
            this.remisAZero();
        } else {
            this.changement = false;
        }
        this.setTitle(this.lesson.getTitle());
        this.initActionBar();
    }// onCreate(Bundle)

    /**
     * Ajoute la vue dans la liste d'écouteurs de {@code UpdateManager}.
     */
    @Override
    protected void onStart() {
        super.onStart();
        UpdateManager um = UpdateManager.getInstance();
        um.addListener(this);
        int status = um.getScheduleStatus(this.lesson.getSchedule());
        if (status != UpdateManager.STATUS_UPDATING) {
            this.init();
        } else {
            this.onUpdate(this.lesson.getSchedule(), status);
        }// if
    }// onStart()

    /**
     * Supprime la vue dans la liste d'écouteurs de {@code UpdateManager}.
     */
    @Override
    protected void onStop() {
        super.onStop();
        UpdateManager.getInstance().removeListener(this);
    }// onStop()

    /**
     * Initialise la barre d'action de la vue.
     */
    private void initActionBar() {
        addActionBarItem(Type.Edit, LessonScreen.ITEM_EDIT);
    }// initActionBar()

    /**
     * Remet à zéro après consultation du changement
     */
    private void remisAZero(){
        Database db = new Database();
            db.updateStatutLesson(this.lesson.getLessonId(), this.lesson.getSchedule(), Lesson.NO_CHANGE);
            db.removeLesson_HistoryWithID(lesson.getLessonId(), lesson.getSchedule());
    }
    
    /**
     * Définition des actions des éléments de la barre d'action.
     */
    @Override
    public boolean onHandleActionBarItemClick(ActionBarItem item, int position) {
        switch (item.getItemId()) {
            case ITEM_EDIT:
                this.mark();
                break;

            default:
                return super.onHandleActionBarItemClick(item, position);
        }// switch()

        return true;
    }// onHandleActionBarItemClick(ActionBarItem, int)

    /**
     * Affiche une boite de dialogue avec les choix de type de cours. Normal,
     * Inmportant, Examen.
     */
    private void mark() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        String[] types = {STATUS_NORMAL, STATUS_IMPORTANT, STATUS_EXAMEN};
        int checkItem = this.lesson.getType();
        builder.setSingleChoiceItems(types, checkItem, new MarkListener(this));
        builder.setTitle("Marquer ce cours");
        builder.setIcon(RESULT_OK);
        Dialog dialog_return = builder.create();
	dialog_return.show() ;
    }// mark()

    /**
     * Lorsqu'il y a eu un changement important dans, on récupére l'historique deu cours, et on met le flag 'changement' à vrai
     */
    private void montrerChangement() {
        Database db = new Database();
        this.oldS = db.getLessonHistoryWithID(this.lesson.getLessonId(), this.lesson.getSchedule());
        this.changement = true;
    }

    /**
     * OnClickListener pour le marquage d'un cour.
     *
     * <p>Récupère le type du cours ans met à jour la base de données.
     *
     * @author Schnell Michaël, Zanette Sébastien
     */
    class MarkListener implements DialogInterface.OnClickListener {

        /**
         * Vue contenant le composant attaché à l'écouteur.
         */
        private LessonScreen container;

        /**
         * Constructeur.
         *
         * @param container View containing the component attached to this
         * listener
         */
        public MarkListener(LessonScreen container) {
            super();
            this.container = container;
        }// MarkListener(LessonScreen)

        /**
         * Définition des action du clique sur le composant attaché.
         *
         * @param	actualView view of the component who has received a click
         * event
         */
        public void onClick(DialogInterface dialog, int item) {
            Lesson dispLesson = this.container.getLesson();
            // A new type has been selected
            if (item != dispLesson.getType()) {
                dispLesson.setType(item);
                Database db = new Database();;
                db.updateLesson(dispLesson.getLessonId(), dispLesson.getSchedule(), dispLesson);
                this.container.init();
            }// if
            dialog.dismiss();
        }// onClick(View)
    }// class MarkListener

    /**
     * Retourne une instance de {@code Lesson} contenant l'information sur la
     * lesson à afficher.
     */
    private Lesson getIntentLesson() {
        return this.getIntent().getParcelableExtra("ade.screen.lesson");
    }// getIntentLesson()

    /**
     * Retourne une instance de {@code Lesson} contenant l'information sur la
     * lesson à afficher.
     *
     * @return	instance of {@code Lesson} containing the information about the
     * displayed lesson
     */
    public Lesson getLesson() {
        return this.lesson;
    }// getLesson()

    /**
     * Initialise la vue avec les valeurs de l'emploi du temps courant.
     */
    public void init() {
        this.items = new ArrayList<Item>();
        
        //Nom du cours
        this.items.add(new SeparatorItem("Nom"));
        this.items.add(new DescriptionItem(this.lesson.getTitle()));
        
        //Date du cours
        this.items.add(new SeparatorItem("Date et Heure"));        
        String formattedDate = new SimpleDateFormat("EEEE dd MMMM",Locale.FRANCE).format(this.lesson.getDate());
        String hours = this.lesson.getTime().substring(this.lesson.getTime().indexOf(' ') + 1);
        if (this.changement && this.oldS.getDate().compareTo(this.lesson.getDate()) != 0) {
            String formattedDateOld = new SimpleDateFormat("EEEE dd MMMM", Locale.FRANCE).format(this.oldS.getDate());
            String hoursOld = this.oldS.getTime().substring(this.oldS.getTime().indexOf(' ') + 1);
            this.items.add(new SubtitleItem(formattedDate + " : " + hours,formattedDateOld + " : " + hoursOld));
        } else {
            this.items.add(new DescriptionItem(formattedDate + " : " + hours));
        }
        
        //Salles
        this.items.add(new SeparatorItem("Lieu"));
        String room = "";
        String oldRoom = "";
        if (!this.lesson.getRoom().equals(""))
            room = this.lesson.getRoom();
        else
            room = NO_ROOM;
        if (this.changement && !this.oldS.getRoom().equals(this.lesson.getRoom())) {  
             if (!this.oldS.getRoom().equals("")){
                oldRoom = this.oldS.getRoom();      
             }else{
                oldRoom = NO_ROOM;
             }    
            this.items.add(new SubtitleItem( room, oldRoom));
        } else {
            this.items.add(new DescriptionItem(room));
            
        }
        
        //Groupes
        this.items.add(new SeparatorItem("Groupe"));
        String[] groups = LessonScreen.parseGroups(this.lesson.getGroups());
        if (groups.length != 0) {
            for (String group : groups) {
                this.items.add(new DescriptionItem(group));
            }// for
        }
        else {
            this.items.add(new DescriptionItem(NO_GROUP));
        }
        
        //Enseignants
        this.items.add(new SeparatorItem("Enseignant"));
        String[] teachers = LessonScreen.parseTeachers(this.lesson.getTeacher());
        if (teachers.length != 0) {
            for (String teacher : teachers) {
                this.items.add(new DescriptionItem(teacher));
            }// for
        }
        else {
            this.items.add(new DescriptionItem(NO_TEACHER));
        }
        
        //Note de cours (affiche la section uniquement lorsqu'il y en a une)
        if (!this.lesson.getNote().equals("")) {
            this.items.add(new SeparatorItem("Note"));
            this.items.add(new DescriptionItem(this.lesson.getNote()));
        }
        
        //Statut
        this.items.add(new SeparatorItem("Statut"));
        this.items.add(new DescriptionItem(LessonScreen.typeToString(this.lesson.getType())));
        
        //Date de création du cours
        this.items.add(new SeparatorItem("Création du cours"));
        this.items.add(new DescriptionItem(this.lesson.getCreated()));

       final ItemAdapter adapter = new ItemAdapter(this, this.items);
       this.setListAdapter(adapter) ;
    }// init()
 
    /**
     * Parse un {@code String} formaté de groupes et retourne une liste
     * contenant tous les groupes.
     *
     * @param groups formatted {@code String} of groups
     *
     * @return	Array containing all the groups
     */
    public static String[] parseGroups(String groups) {
        String[] g = groups.split(",");
        if(g.length == 1 && g[0].equals("")){
            g = new String[0];
        }
        return g;
    }// parseGroup(String)

    /**
     * Parse un {@code String} formaté d'enseignant et retourne une liste
     * contenant tous les enseignants.
     *
     * @param teachers chaine de caractères d'enseignant séparés par des virgules
     * @return	Array containing all the teachers
     */
    public static String[] parseTeachers(String teachers) {
        String[] g = teachers.split(",");
        if(g.length == 1 && g[0].equals("")){
            g = new String[0];
        }
      return g;
    }// parseTeachers(String)

    /**
     * Retourne une représentation textuelle d'une type de cour. <p>Les valeurs
     * sont : 0 (normal), 1 (important) and 2 (examen).
     *
     * @param type code for the lesson type
     * @return	name of the lessen type
     */
    public static String typeToString(int type) {
        String[] items = {STATUS_NORMAL, STATUS_IMPORTANT, STATUS_EXAMEN};
        if (type < 0 || type >= items.length) {
            return items[0];
        }// if
        return items[type];
    }// typeToString(int)

    /**
     * Utilisé pour l'affichage d'une boite de dialogue lorque l'emploi du temps
     * est en cours de mise à jour.
     */
    public void onUpdate(Object... args) {
        try {
            String scheduleName = (String) args[0];
            int scheduleState = (Integer) args[1];
            if (scheduleName.equals(this.lesson.getSchedule())) {
                if (scheduleState == UpdateManager.STATUS_UPDATING) {
                    if (this.updateDialog == null) {
                        this.updateDialog = ProgressDialog.show(this,
                                "Chargement", "Mise à jour en cours ...",
                                true, true, new UpdateCancelListener(this));
                    }// if
                } else {
                    if (this.updateDialog != null) {
                        this.updateDialog.dismiss();
                        this.updateDialog = null;
                    }// if
                }// if
            }// if
        } catch (Exception e) {
            /**
             * Nothing to be done.
             */
        }//try
    }// onUpdate(Object...)

    /**
     * OnCancelListener pour le bouton "annuler", si l'utilisateur souhaite
     * quitter cette vue pendant que l'emploi du temps est synchronisé.
     *
     * @author	Schnell Michaël, Zanette Sébastien
     */
    class UpdateCancelListener extends Object implements OnCancelListener {

        /**
         * Vue contenant le composant attaché à l'écouteur.
         */
        protected LessonScreen container;

        /**
         * Constructeur.
         *
         * @param container View containing the component attached to this
         * listener
         */
        public UpdateCancelListener(LessonScreen container) {
            super();
            this.container = container;
        }// UpdateCancelListener(LessonScreen)

        /**
         * Définition l'action annuler.
         *
         * @param	actualView view of the component who has received a click
         * event
         */
        public void onCancel(DialogInterface dialog) {
            dialog.dismiss();
            this.container.onBackPressed();
        }// onCancel(DialogInterface)
    }// class UpdateCancelListener
}// class LessenScreen
